package cn.coderliu.voteweb.webcontroller;

import cn.coderliu.voteweb.common.util.DateUtil;
import cn.coderliu.voteweb.common.util.HttpUtil;
import cn.coderliu.voteweb.common.util.R;
import cn.coderliu.voteweb.common.util.StringUtil;
import cn.coderliu.voteweb.entity.Param;
import cn.coderliu.voteweb.entity.Program;
import cn.coderliu.voteweb.entity.Record;
import cn.coderliu.voteweb.entity.Time;
import cn.coderliu.voteweb.service.ParamService;
import cn.coderliu.voteweb.service.ProgramService;
import cn.coderliu.voteweb.service.RecordService;
import cn.coderliu.voteweb.service.TimeService;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;

import java.text.ParseException;
import java.util.*;

/**
 * @author liu
 */
@Controller
public class ViewController {

    @Autowired
    ProgramService programService;
    @Autowired
    RecordService recordService;
    @Autowired
    ParamService paramService;
    @Autowired
    TimeService timeService;

    @Autowired
    JdbcTemplate jdbcTemplate;


    @GetMapping(value = {"/vote", "/"})
    public String vote(String code, Model model) {

        if (StringUtil.isNotEmpty(code)) {//APPID&secret=SECRET&code=CODE
            String jsonString = HttpUtil.doGet("https://api.weixin.qq.com/sns/oauth2/access_token?appid=wx3d6a0b8703941b5b&secret=8f00f882d7e9b4360506ef38006c9381&code=" + code + "&grant_type=authorization_code");
            Gson g = new Gson();
            JsonObject jsonObject = g.fromJson(jsonString, JsonObject.class);
            if (jsonObject.get("openid") != null) {
                model.addAttribute("appId", jsonObject.get("openid").toString());
            }
        }
        return "/vote";
    }

    @GetMapping(value = "/page")
    public String page() {
        return "/page";
    }

    @GetMapping(value = "/voteJson/{appId}")
    @ResponseBody
    public Object voteJson(@PathVariable String appId) {
        List<Param> params = paramService.jpqlSearch("from Param e where e.type=1");
        String sql = "SELECT  " +
                " id, " +
                " NAME as name, " +
                " person," +
                "gro  " +
                "FROM " +
                " program  " +
                "WHERE " +
                " gro='" + Integer.valueOf(params.get(0).getName()) + "'";
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
        List<Record> records = recordService.jpqlSearch("from Record e where e.appId='" + appId + "'");
        for (Record r : records) {
            for (Map<String, Object> m : maps) {
                if (m.get("id").toString().equals(r.getProgramId().toString())) {
                    m.put("isVote", 1);
                }
            }
        }

        Map<String, Object> result = new HashMap<>(16);
        result.put("statusCode", 200);
        result.put("totalPages", maps.size());
        result.put("statusMsg", null);
        result.put("data", maps);
        return result;
    }

    /**
     * 投票
     */

    @GetMapping(value = "/subVote")
    @ResponseBody
    public Object subVote(String appId, Integer id, Integer gro) {
        String name = paramService.jpqlSearch("from Param e where e.type=1").get(0).getName();
        if(!gro.toString().equals(name)){
            return R.ok("111111", "！");
        }
        List<Time> times = timeService.jpqlSearch("from Time e where e.groId=" + gro);
        if (times.get(0).getStartTime() == null) {
            return R.ok("100001", "投票未开始！");
        }
        if (times.get(0).getStartTime() != null && times.get(0).getEndTime() != null) {
            return R.ok("100001", "投票已结束！");
        }



        List<Record> records = recordService.jpqlSearch("from Record e where e.appId='" + appId + "' and e.gro=" + gro + " and e.programId=" + id);
        if (records != null && records.size() > 0) {
            return R.ok("100001", "您已经投过票了");
        } else {
            Record r = new Record(appId, id, gro, new Date());
            recordService.update(r);
            return R.ok();
        }
    }

    @ResponseBody
    @GetMapping(value = "/delete/{appId}/{paramId}/{gro}")
    public Object deleteRecord(@PathVariable String appId,
                               @PathVariable Long paramId,
                               @PathVariable Integer gro) {
        String name = paramService.jpqlSearch("from Param e where e.type=1").get(0).getName();
        if(!gro.toString().equals(name)){
            return R.ok("111111", "！");
        }
        List<Time> times = timeService.jpqlSearch("from Time e where e.groId=" + gro);
        if (times.get(0).getStartTime() == null) {
            return R.ok("100001", "投票未开始！");
        }
        if (times.get(0).getStartTime() != null && times.get(0).getEndTime() != null) {
            return R.ok("100001", "投票已结束！");
        }


        recordService.batchUpdate("delete Record e where e.appId='" + appId + "' and e.programId=" + paramId + " and e.gro=" + gro);
        return R.ok();
    }

    @GetMapping(value = "/admin")
    public String admin() {
        return "/admin";
    }


    @GetMapping(value = "/ctrlParam/{param}")
    @ResponseBody
    public Object ctrlParam(@PathVariable String param) {
        paramService.batchUpdate("update Param e set e.name='" + param.trim() + "'");
        return R.ok();
    }

    @GetMapping(value = "/data")
    @ResponseBody
    public Object data(String param) throws ParseException {



        List<Param> params = paramService.jpqlSearch("from Param e where e.type=1");
        if(!StringUtil.isNotEmpty(param)){
            param=params.get(0).getName();
        }

        List<Time> times = timeService.jpqlSearch("from Time e where e.groId=" + param);
        String sql = "select id ,name ,'0' as num from program where gro=" + param;
        List<Map<String, Object>> program = jdbcTemplate.queryForList(sql);
        String recordSql = "select count(id) as num ,program_id as programId from record where gro=" + param;
        if (times.get(0).getStartTime() != null) {
            recordSql += " and create_time >='" + DateUtil.formatToDateTimeStr(times.get(0).getStartTime()) + "'";
        }
        if (times.get(0).getEndTime() != null) {
            recordSql += " and create_time <='" + DateUtil.formatToDateTimeStr(times.get(0).getEndTime()) + "'";
        }
        recordSql += " group by programId";
        List<Map<String, Object>> recordMap = jdbcTemplate.queryForList(recordSql);
        for (Map<String, Object> p : program) {
            for (Map<String, Object> r : recordMap) {
                if (p.get("id").toString().equals(r.get("programId").toString())) {
                    p.put("num", Integer.valueOf(p.get("num").toString()) + Integer.valueOf(r.get("num").toString()));
                }
            }
        }

        Collections.sort(program, (o1, o2) -> {
            int map1value = Integer.valueOf(o1.get("num").toString());
            int map2value = Integer.valueOf(o2.get("num").toString());
            return map2value - map1value;
        });
        Map<String, Object> m = new HashMap<>(16);
        m.put("statusCode", "200");
        m.put("totalPages", program.size());
        m.put("statusMsg", "");
        m.put("data", program);
        return m;
    }

    @GetMapping(value = "/time/{param}")
    @ResponseBody
    public Object time(@PathVariable String param) throws ParseException {
        List<Param> params = paramService.jpqlSearch("from Param e where e.type=1");
        String sql = "update Time e set ";
        if (param.equals("1")) {
            sql += " e.startTime='" + DateUtil.formatToDateTimeStr(new Date()) + "'";
        } else {
            sql += " e.endTime='" + DateUtil.formatToDateTimeStr(new Date()) + "'";
        }
        sql += " where e.groId=" + params.get(0).getName();
        timeService.batchUpdate(sql);
        return R.ok();
    }


    @GetMapping(value = "/finals")
    @ResponseBody
    public Object finals() {

        List<Program> programs = programService.jpqlSearch("from Program e where e.gro=2");

        if (programs == null || programs.size() == 0) {
            String sql = "select " +
                    "  count(id) as num, " +
                    "  program_id as id " +
                    "from record " +
                    "group by program_id " +
                    "  order by  num desc " +
                    "limit 5";
            List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
            String ids = "";

            for (int i = 0; i < maps.size(); i++) {
                if (ids.split(",").length< 5) {
                    ids += maps.get(i).get("id").toString() + ",";
                }
            }
            if (ids.length() > 0) {
                ids = ids.substring(0, ids.length() - 1);
            }

            List<Program> programList = programService.jpqlSearch("from Program e where e.id in (" + ids + ")");
            programList.forEach(item -> {
                Program p = new Program();
                p.setName(item.getName());
                p.setGro(2);
                p.setPerson(item.getPerson());
                programService.update(p);
            });
            paramService.batchUpdate("update Param e set e.name='2' where e.type=1");
        }
        return R.ok();
    }

    @ResponseBody
    @GetMapping(value = "/getTime/{param}")
    public Object getTime(@PathVariable String param){
        List<Time> times = timeService.jpqlSearch("from Time e where e.groId=" + param);
        return times.get(0);
    }
    @ResponseBody
    @GetMapping(value = "/getParam")
    public Object getParam(){
       return paramService.jpqlSearch("from Param e where e.type=1").get(0);
    }

}
